package com.ztgf.order.service.pay;

import com.alibaba.fastjson.JSON;
import com.ztgf.common.constant.Result;
import com.ztgf.common.enums.CodeEnum;
import com.ztgf.dubbo.exception.ServiceException;
import com.ztgf.logistics.models.dto.deppon.LogisticsUserDTO;
import com.ztgf.logistics.models.service.deppon.ILogisticsUserMoneyLogService;
import com.ztgf.logistics.models.service.deppon.ILogisticsUserService;
import com.ztgf.order.models.bo.pay.PayOrderSaveBO;
import com.ztgf.order.models.dto.pay.PayOrderLogDTO;
import com.ztgf.order.models.service.pay.IPayLogisticsService;
import com.ztgf.order.models.service.pay.IPayOrderLogService;
import com.ztgf.order.models.vo.pay.PayOrderVO;
import com.ztgf.order.models.vo.pay.PayShopVO;
import com.ztgf.pay.models.bo.PayOrderMotherSaveBO;
import com.ztgf.pay.models.dto.PayOrderDTO;
import com.ztgf.pay.models.service.IPayUserRechargeService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description:
 * @Author: mxli
 * @Date: 2021-09-14 11:29
 **/
@DubboService
public class PayLogisticsServceImpl implements IPayLogisticsService {

    @Autowired
    private IPayOrderLogService payOrderLogService;
    @DubboReference
    private ILogisticsUserService logisticsUserService;
    @DubboReference
    private ILogisticsUserMoneyLogService logisticsUserMoneyLogService;
    @DubboReference
    private IPayUserRechargeService payUserRechargeService;
    @Autowired
    private IPayNotifyService payNotifyService;

    @Value("${zj-pay.page-pay-url-logistics-margin}")
    private String pageLogisticsMarginUrl; //物流保证金
    @Value("${zj-pay.page-pay-url-logistics-bill}")
    private String pageLogisticsBillUrl; //物流账单


    /**
     * 缴纳物流保证金
     * @param bo id传shopId
     * @param payOrderVO
     * @param userId
     * @param userName
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void saveLogisticsPayMargin(PayOrderSaveBO bo, PayOrderVO payOrderVO, Long shopId, Long userId, String userName) {
        BigDecimal money = BigDecimal.ZERO;

        List<PayShopVO> list = payOrderLogService.queryLogisticsMargin(shopId);
        if(list == null || list.size() != 1){
            throw new ServiceException(CodeEnum.FAIL_200030);
        }

        for(PayShopVO vo : list){
            money = money.add(vo.getMoney());
        }

        PayOrderLogDTO logDTO = payOrderLogService.newLogDTO(null, null, null, shopId, null, null
                , userId, userName, shopId, bo.getPayType(), 1, 15
                , 2, bo.getBankId(), bo.getBankName(), money);
        if(bo.getPayType() == 0){
            logDTO.setStatus(2);
        }
        boolean flag = payOrderLogService.insert(logDTO);
        if(!flag){
            throw new ServiceException(CodeEnum.FAIL_200030);
        }
        if(bo.getPayType() == 0){
            payNotifyService.saveRechargeSuccess(logDTO);
        } else {
            payOrderLogService.saveRechargeByOnlineBank(payOrderVO, shopId, money, bo.getBankId(), logDTO.getId(), "充值-缴物流保证金", pageLogisticsMarginUrl);
        }
    }

    /**
     * 解冻物流保证金
     * @param shopId
     * @param userId
     * @param userName
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void saveLogisticsUnfreezeMarginMoney(Long shopId, BigDecimal money, Long userId, String userName) {
        LogisticsUserDTO userDTO = logisticsUserService.selectById(shopId);
        if(money == null || userDTO == null || money.compareTo(BigDecimal.ZERO) <= 0 || money.compareTo(userDTO.getMguaranteeMoney()) > 0){
            throw new ServiceException(CodeEnum.FAIL_200031);
        }
        PayOrderLogDTO logDTO = payOrderLogService.newLogDTO(null, null, null, shopId, null, null
                , userId, userName, shopId, 0, 0, 16
                , 3, null, null, money);
        logDTO.setStatus(2);
        boolean flag = payOrderLogService.insert(logDTO);
        if(!flag){
            throw new ServiceException(CodeEnum.FAIL_200030);
        }
        LogisticsUserDTO newUserDTO = new LogisticsUserDTO();
        newUserDTO.setMguaranteeMoney(userDTO.getMguaranteeMoney().subtract(money));
        if(userDTO.getMguaranteeMoneyQuota().compareTo(newUserDTO.getMguaranteeMoney()) != 0){
            newUserDTO.setType(0);//保证金不足  变为现结用户
        }
        logisticsUserService.updateMoney(logDTO.getId(), newUserDTO, userDTO, money.negate(), 1, logDTO.getCreateUserId(), logDTO.getCreateUserName());
        payOrderLogService.saveUnfreezeMoney(logDTO.getPayShopId(), logDTO.getId(), logDTO.getMoney(), "解冻，物流保证金");

    }

    /**
     * 扣除保证金
     * @param shopId
     * @param money
     * @param userId
     * @param userName
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void saveLogisticsDeductMargin(Long shopId, BigDecimal money, String notes, Long userId, String userName) {
        LogisticsUserDTO userDTO = logisticsUserService.selectById(shopId);
        if(money == null || userDTO == null || money.compareTo(BigDecimal.ZERO) <= 0 || money.compareTo(userDTO.getMguaranteeMoney()) > 0){
            throw new ServiceException(CodeEnum.FAIL_200031);
        }

        //直接到账
        PayOrderMotherSaveBO saveBO = new PayOrderMotherSaveBO();
        saveBO.setMoney(money);
        saveBO.setPaymentUserId(shopId);

        List<PayOrderLogDTO> logDTOList = new ArrayList<>();
        List<PayOrderDTO> orderDTOList = new ArrayList<>();

        //订单金额
        // 业务标示:
        // 余额支付：A00 普通订单支付,B00 收款方收款成功后，再冻结资金, B01 付款方解冻资金后，再支付给收款方；
        // 网银支付： A00 入金并支付 B00 收款方收款成功后，再 冻结资金
        String trsFlag = "B01";
        int moneyStatus = 0;//金额状态：0未冻结，1冻结

        //金额类型：0订单金额，1佣金、2缴纳保证金、3年费、4采购申请平台砍价、5砍价手续费、6重复支付，7售后退款、8解冻保证金、9扣除保证金、10取消订单退款
        //orderType 支付订单类型：0支付，1退款
        // 余额-订单支付 订单编号：2020111200000003
        // 余额-订单支付 订单编号：2020111200000003
        String moneyUsage = "余额-扣除物流保证金";
        payOrderLogService.savePayParams(logDTOList, orderDTOList, null, null, null, 0L
                , null, null, userId, userName, shopId, 0, moneyStatus
                , 17, 0, saveBO.getBankId(), saveBO.getBankName(), money, moneyUsage, null, trsFlag, notes);

        //添加日志
        payOrderLogService.insertBatch(logDTOList);
        saveBO.setChildOrderList(JSON.toJSONString(orderDTOList));
        payOrderLogService.saveHttpPayBalance(saveBO);
    }

    /**
     * 支付物流账单
     * @param bo
     * @param payOrderVO
     * @param userId
     * @param userName
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void saveLogisticsPayBillMoney(PayOrderSaveBO bo, PayOrderVO payOrderVO, Long shopId, Long userId, String userName) {


        BigDecimal money = BigDecimal.ZERO;
        List<PayShopVO> list = payOrderLogService.queryLogisticsBill(bo.getIds(), shopId);
        if(list == null || list.size() == 0){
            throw new ServiceException(CodeEnum.FAIL_200030);
        }

        PayOrderMotherSaveBO saveBO = new PayOrderMotherSaveBO();
        saveBO.setBankId(bo.getBankId());
        saveBO.setBankName(bo.getBankName());

        List<PayOrderLogDTO> logDTOList = new ArrayList<>();
        List<PayOrderDTO> orderDTOList = new ArrayList<>();
        for(PayShopVO vo : list){

            money = money.add(vo.getMoney());


            //订单金额
            // 业务标示:
            // 余额支付：A00 普通订单支付,B00 收款方收款成功后，再冻结资金, B01 付款方解冻资金后，再支付给收款方；
            // 网银支付： A00 入金并支付 B00 收款方收款成功后，再 冻结资金
            String trsFlag = "A00";
            int moneyStatus = 1;

            //List<PayOrderLogDTO> logDTOList, List<PayOrderDTO> orderDTOList
            //            , Long orderId, Long orderPeriodsId, Integer periods, Long recvShopId,Long commodityBargainId, Long oldPayOrderLogId
            //            ,Long userId, String userName, Long payShopId, Integer payType, Integer moneyStatus, Integer businessType
            //            ,Integer orderType, String bankId, String bankName, BigDecimal money, String moneyUsage, String commodityMsg
            //            ,String trsFlag
            //金额类型：0订单金额，1佣金、2缴纳保证金、3年费、4采购申请平台砍价、5砍价手续费、6重复支付，7售后退款、8解冻保证金、9扣除保证金、10取消订单退款
            //orderType 支付订单类型：0支付，1退款
            // 余额-订单支付 订单编号：2020111200000003
            String moneyUsage = "";
            if(bo.getPayType() == 0){//余额支付
                moneyUsage = "余额-物流账单支付 账单编号："  + vo.getId();
            } else {//网银支付
                moneyUsage = "网银-物流账单支付 账单编号："  + vo.getId();
            }
            payOrderLogService.savePayParams(logDTOList, orderDTOList, vo.getId(), vo.getId(), null, null
                    , null, null, userId, userName, shopId, bo.getPayType(), moneyStatus
                    , 18, 0, bo.getBankId(), bo.getBankName(), vo.getMoney(), moneyUsage, null, trsFlag);

        }
        saveBO.setPaymentUserId(shopId);
        saveBO.setNotifyPageUrl(pageLogisticsBillUrl);
        //添加日志
        payOrderLogService.insertBatch(logDTOList);
        saveBO.setMoney(money);
        saveBO.setChildOrderList(JSON.toJSONString(orderDTOList));

        payOrderLogService.saveHttpPay(saveBO, bo, payOrderVO);
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public Result updateMguaranteeMoneyQuota(Long shopId, BigDecimal money, Long userId, String userName) {
        LogisticsUserDTO dto = logisticsUserService.selectById(shopId);
        if(money == null || dto == null || money.compareTo(BigDecimal.ZERO) < 0){
            return new Result<>(CodeEnum.FAIL_100002);
        }
        LogisticsUserDTO newDTO = new LogisticsUserDTO();
        BigDecimal unfreezeMarginMoney = BigDecimal.ZERO;
        newDTO.setMguaranteeMoneyQuota(money);
        if(money.compareTo(dto.getMguaranteeMoney()) > 0){//大于已缴纳保证金额，不处理
            newDTO.setStatus(1);
        } else if(money.compareTo(dto.getMguaranteeMoney()) == 0) {//小于则退还保证金 ,解冻金额
            newDTO.setStatus(0);
        } else {//小于则退还保证金 ,解冻金额
            unfreezeMarginMoney = dto.getMguaranteeMoney().subtract(money);
            newDTO.setMguaranteeMoney(money);
        }
        logisticsUserService.updateMoney(null, newDTO, dto, money, 3, userId, userName);
        //解冻金额
        if(unfreezeMarginMoney.compareTo(BigDecimal.ZERO) > 0){
            logisticsUserMoneyLogService.insert(null, shopId, 1, unfreezeMarginMoney.negate(),  money, money, dto.getLogisticsMoneyQuota(), dto.getLogisticsMoneyUsed(), dto.getLogisticsMoneyUnused(), dto.getLogisticsMoneyUsedScale(), userId, userName, CodeEnum.FAIL_200021);
            PayOrderLogDTO logDTO = payOrderLogService.newLogDTO(null, null, null, shopId, null, null
                    , userId, userName, shopId, 0, 0, 16
                    , 3, null, null, unfreezeMarginMoney.negate());
            logDTO.setStatus(2);
            boolean flag = payOrderLogService.insert(logDTO);
            if(!flag){
                throw new ServiceException(CodeEnum.FAIL_200030);
            }
            payOrderLogService.saveUnfreezeMoney(logDTO.getPayShopId(), logDTO.getId(), unfreezeMarginMoney, "解冻，物流保证金");
        }
        return new Result<>();
    }
}
